package com.sample.mockito.test;

import org.junit.Assert;
import org.junit.Test;
import org.mockito.InOrder;
import org.mockito.invocation.InvocationOnMock;
import org.mockito.stubbing.Answer;

import java.util.LinkedList;
import java.util.List;

import static org.mockito.Mockito.*;

/*
https://www.cnblogs.com/s1328/p/4626757.html
 */
public class SampleTest04 {

    @Test
    public void sampleTest10() {
        LinkedList mockedList = mock(LinkedList.class);

        when(mockedList.add("some arg"))
                .thenThrow(new RuntimeException())
                .thenReturn(true);

        try {
            mockedList.add("some arg");
            Assert.fail("Should not be here");
        }catch (RuntimeException e){

        }

        System.out.println(mockedList.add("some arg"));


        when(mockedList.get(0))
                .thenReturn("hello", "world", "!!!!");

        System.out.println(mockedList.get(0));
        System.out.println(mockedList.get(0));
        System.out.println(mockedList.get(0));
    }

    @Test
    public void sampleTest11() {
        LinkedList mockedList = mock(LinkedList.class);

        when(mockedList.get(anyInt())).thenAnswer(new Answer() {
                    @Override
                    public Object answer(InvocationOnMock invocation) {
                        Object[] args = invocation.getArguments();
                        Object mock = invocation.getMock();
                        return "called with arguments: " + args[0];
                    }
                });
        System.out.println(mockedList.get(0));
        System.out.println(mockedList.get(1));
        System.out.println(mockedList.get(2));
    }

    @Test(expected = RuntimeException.class)
    public void sampleTest12() {
        LinkedList mockedList = mock(LinkedList.class);

        //not work
        //when(mockedList.clear()).thenThrow(new RuntimeException());
        doThrow(new RuntimeException()).when(mockedList).clear();

        mockedList.clear();
    }



    @Test
    public void sampleTest13() {
        List list = new LinkedList();
        List spy = spy(list);

        //optionally, you can stub out some methods:
        when(spy.size()).thenReturn(100);

        //IndexOutOfBoundsException
        //when(spy.get(0)).thenReturn("foo");
        doReturn("foo").when(spy).get(0);
        System.out.println(spy.get(0));


        //using the spy calls *real* methods
        spy.add("one");
        spy.add("two");

        //prints "one" - the first element of a list
        System.out.println(spy.get(0));
        System.out.println(spy.get(1));

        //size() method was stubbed - 100 is printed
        System.out.println(spy.size());

        //optionally, you can verify
        verify(spy).add("one");
        verify(spy).add("two");
    }



}
